/*
    做法：
        枚举，标识每个商品节点只能与比它小的等级交易，这样一直在M区间内向下交易，简化了
        判断条件，这个区间内的所有商品都是可以参与交易的。如此枚举可以保证全部情况都被遍历。

        在dijkstra算法中，假设0号节点为探险家，目的是找到0号到1号的最短距离，因为在图中通过
        所有没有被标记的节点都可以交易，所以问题为使用dijkstra算法找到0到1的最短路径，并返回。

        在枚举过程中，当新的枚举值的dijkstra算法得出的距离小于目前的最短距离时，更新最短距离。
*/
#include<iostream>
#include<cstring>

using namespace std;

const int inf=1e7;

int M,N;    //最大等级差和商品总数
int price[101][101];     //price[i][j]表示拥有第i件可以用这个价格换第j件商品
int level[101];     //拥有者等级
int x[101];     //拥有的替代品数量

int dist[101];  //从一个假设的“源”出发到各节点的最短距离
bool isFound[101];  //节点是否被检查过

int dijkstra(){
    int node;   //记录dijkstra算法中每步的最短路径节点
    int min_dis;

    for(int i=1;i<=N;i++){  //初始化距离
        dist[i]=price[0][i];
    }

    for(int i=1;i<=N;i++){  //枚举最多N次可实现全部松弛
        node=0;
        min_dis=inf;    //松弛初值
        for(int j=1;j<=N;j++){
            if(!isFound[j]&&dist[j]<min_dis){   //更新最短距离和节点
                min_dis=dist[j];
                node=j;
            }
        }

        if(node==0){    //无法继续松弛，即结束
            break;
        }

        isFound[node]=true; //标记最短节点

        for(int j=1;j<=N;j++){      //更新各节点最短距离
            if(!isFound[j]&&price[node][j]>0&&dist[j] > dist[node] + price[node][j]){
                dist[j]=dist[node]+price[node][j];
            }
        } 
    }
    return dist[1]; //1号商品为国王允诺
}

int main(void){
    memset(price,0,sizeof(price));   
    memset(level,0,sizeof(level));   
    memset(dist,inf,sizeof(dist));   
    memset(isFound,false,sizeof(isFound));  
	
    cin>>M>>N;   
    for(int i=1;i<=N;i++)   
    {   
        cin>>price[0][i]>>level[i]>>x[i];//price[0][i]物品i无替代品时的原价
  
        for(int j=1;j<=x[i];j++)   
        {   
            int t,u;
			cin>>t>>u;
            price[t][i]=u;//物品i在有第t号替代品情况下的优惠价，即点t到点i的权值
        }   
    }

    int tmp_price;
    int maxlv;
    int minprice=inf;

    for(int i=1;i<=N;i++){  //枚举商品等级，只跟等级低的且符合范围的商品交易
        maxlv=level[i];
        for(int j=1;j<=N;j++){
            if(level[j]>maxlv||maxlv-level[j]>M){
                isFound[j]=true;    //不符合的商品，用“已经查找过”标记
            }
            else{
                isFound[j]=false;
            }
        }
        tmp_price=dijkstra();
        if(minprice>tmp_price){     //对结果更新最短
            minprice=tmp_price;
        }
    }
    cout<<minprice<<endl;
    return 0;
}